package com.fdb.efp.cus.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.fdb.efp.cus.service.dao.CompanyWhiteListDao;
import com.fdb.efp.cus.service.domain.CompanyWhiteList;
import com.gdrcu.efp.cus.common.CompanyStatusEnum;
import com.gdrcu.efp.cus.common.CompanyTypeEnum;
import com.fdb.basic.framework.core.util.*;
import com.fdb.efp.console.common.ConsoleConstant;
import com.fdb.efp.console.common.YedEnums;
import com.fdb.efp.console.service.facade.KubUserService;
import com.fdb.efp.console.service.vo.KubUserVO;
import com.fdb.efp.cus.service.facade.*;
import com.fdb.efp.cus.service.vo.*;
import com.fdb.efp.esb.common.constant.InstitutionEnums;
import com.fdb.efp.esb.common.constant.MsLoanConstant;
import com.fdb.efp.esb.service.bo.req.hlw.ReqAlarmJudgementBean;
import com.fdb.efp.esb.service.bo.req.sx.QryRptsInfArryBean;
import com.fdb.efp.esb.service.bo.req.sx.YedCreditRiskApproveReq;
import com.fdb.efp.esb.service.bo.req.yed.YedCompanyInfoRequestBean;
import com.fdb.efp.esb.service.bo.req.yed.YedGjjAccInfoReqBean;
import com.fdb.efp.esb.service.bo.req.yed.YedGjjCompnayInfoRequestBean;
import com.fdb.efp.esb.service.bo.resp.hlw.RespAlarmJudgementBean;
import com.fdb.efp.esb.service.bo.resp.sx.YedCreditRiskApproveResp;
import com.fdb.efp.esb.service.bo.resp.yed.*;
import com.fdb.efp.esb.service.facade.esb.EsbService;
import com.fdb.efp.esb.service.facade.hlw.AlarmJudgementService;
import com.fdb.efp.esb.service.facade.yed.YedCompanyInfoService;
import com.fdb.efp.loan.service.facade.AccLoanService;
import com.fdb.efp.loan.service.vo.AccLoanVO;
import com.fdb.efp.nls.service.facade.ed.LimitControlsService;
import com.fdb.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.fdb.efp.nls.service.vo.NlsApplyInfoVO;
import com.fdb.efp.nls.service.vo.sx.NlsCreditInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * Description:企业白名单补录实现类
 * Date:2020/8/5 14:44
 * Create by :企业白名单补录实现类
 */
@Service("companyWhiteListRecordService")
public class CompanyWhiteListRecordServiceImpl extends CompanyWhiteListAbstart implements CompanyWhiteListRecordService {

    private final Logger logger = LoggerFactory.getLogger(CompanyWhiteListRecordServiceImpl.class);

    private static AtomicInteger pengYuanCount = new AtomicInteger(1);
    private static AtomicInteger gjjCount = new AtomicInteger(1);

    //优e贷产品出账机构
    private static final String ZHI_HUI_CHU_ZHANG_ORG="0328";
    //优e贷产品管户机构
    private static final String ZHI_HUI_GUAN_HU_ORG="0328";
    //优e贷产品智慧银行虚拟推荐人
    private static final String ZHI_HUI_XU_NI_REF="XN0328";
    //优e贷产品虚拟柜员前缀
    private static final String XU_NI="XN";

    private static final String PENG_YUAN_PRE="COMPANY_WHITE_LIST";

    @Autowired
    private CompanyWhiteListDao companyWhiteListDao;

    @Autowired
    private GzReturnInfoService gzReturnInfoService;

    @Autowired
    private YedCompanyInfoService yedCompanyInfoService;

    @Autowired
    private AcctInfoService acctInfoService;

    @Autowired
    private AcctInfoDetailService acctInfoDetailService;

    @Autowired
    private AcctInfoGetService acctInfoGetService;

    @Autowired
    private AcctInfoLoanService acctInfoLoanService;

    @Autowired
    @Qualifier("accLoanService")
    private AccLoanService accLoanService;

    @Autowired
    @Qualifier("limitControlsService")
    private LimitControlsService limitControlsService;

    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;

    @Autowired
    @Qualifier("yedCreditRiskApproveService")
    private EsbService<YedCreditRiskApproveReq, YedCreditRiskApproveResp> creditRiskApproveService;

    @Autowired
    @Qualifier("cusReferrerInfoService")
    private CusReferrerInfoService cusReferrerInfoService;

    @Autowired
    private KubUserService kubUserService;
    @Autowired
    private CompanyWhiteListService companyWhiteListService;

    @Autowired
    @Qualifier("alarmJudgementService")
    private AlarmJudgementService alarmJudgementService;

    @Autowired
    private RedisLockCluster redisLockCluster;

    @Autowired
    private CusOrgEditService cusOrgEditService;

    /**
     * description：白名单补录
     * param：参数传入，证件号码,证件类型,城市,客户姓名
     * return:
     * date: 2020/8/5 15:44
     * auther: gcb
     */
    @Override
    public void saveCompanyWhiteList(NlsCreditInfoVO nlsCreditInfoVO) {
        try {
            long startTime = System.currentTimeMillis();
            logger.info("白名单自动补录流程开始,授信流水号为"+nlsCreditInfoVO.getLmtApplySeq());
            String certType =nlsCreditInfoVO.getCertType();
            String certCode = nlsCreditInfoVO.getCertCode();
            String city = nlsCreditInfoVO.getCity();
            String name = nlsCreditInfoVO.getCusName();
            String code = nlsCreditInfoVO.getCertCode();
            if(StringUtils.isBlank(city)){
                city="广州";
            }
            //校验参数
            if (StringUtils.isBlank(certType) || StringUtils.isBlank(certCode) || StringUtils.isBlank(name)) {
                logger.info("证件类型或者证件号码为空或者申请城市为空，请检查！传入参数证件类型为：{}，证件号码为：{},授信流水号为：{}", certType, certCode,nlsCreditInfoVO.getLmtApplySeq());
            }
            String dfCompanyName = null;
            String gjjCompanyName = null;
            String gjjRegisterAddr = null;
            //查询行内代发工资企业名称
            GzReturnInfoVO gzInfo = new GzReturnInfoVO();
            gzInfo.setCertNum(certCode);
            gzInfo.setCertTypeCd(certType);

            List<GzReturnInfoVO> gzReturnInfoVOS = gzReturnInfoService.queryCertCodeAndCertType(gzInfo);
            if (gzReturnInfoVOS == null || gzReturnInfoVOS.size() == 0) {
                logger.info("无行内代发工资企业名称，授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
            } else {
                dfCompanyName = gzReturnInfoVOS.get(0).getAgentCustName();
            }
            //查询公积金企业信息
            YedGjjAccNoInfoResponseBean accNoResp = null;
            try{
                List<AcctInfoVO> acctInfoVOS = getAcctInfoVOS(certType, certCode);
                if(acctInfoVOS != null && acctInfoVOS.size() >= 1){
                    String date = DateUtility.getCurrDate();
                    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
                    Date parse = sd.parse(acctInfoVOS.get(0).getCreateTime());
                    String format = sd.format(parse);
                    int days = DateUtility.getBetweenDays(format, date);
                    if(days > 30){
                        accNoResp = getYedGjjAccNoInfoResponseBean(certType, certCode, name);
                        if(accNoResp != null){
                            gjjCompanyName = accNoResp.getCorpNm();
                            gjjRegisterAddr = accNoResp.getCorpAddr();
                        }
                    }else{
                        gjjCompanyName = acctInfoVOS.get(0).getCorpNm();
                    }
                }else{
                    accNoResp = getYedGjjAccNoInfoResponseBean(certType, certCode, name);
                    if(accNoResp != null){
                        gjjCompanyName = accNoResp.getCorpNm();
                        gjjRegisterAddr = accNoResp.getCorpAddr();
                    }
                }
                //校验企业名称
                if (StringUtils.isBlank(dfCompanyName) && StringUtils.isBlank(gjjCompanyName)) {
                    logger.info("无行内代发企业名称和公积金代发企业名称，授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
                }else{
                    boolean dfflag = true;
                    if(StringUtils.isNotBlank(dfCompanyName)){
                        List<CompanyWhiteList> fdCompanyWhiteLists = queryCompanyLikeName(dfCompanyName);
                        if(Objects.nonNull(fdCompanyWhiteLists)){
                            List<String> collect = fdCompanyWhiteLists.stream().map(CompanyWhiteList::getCompanyName).collect(Collectors.toList());
                            for(String str:collect){
                                if(str.equals(dfCompanyName)){
                                    logger.info("行内代发在白名单表有数据，不做补录。授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
                                    dfflag = false;
                                }
                            }
                        }
                    }else if(StringUtils.isBlank(dfCompanyName)){
                        dfflag = false;
                    }
                    boolean gjjflag = true;
                    if(StringUtils.isNotBlank(gjjCompanyName)){
                        List<CompanyWhiteList> gjjCompanyWhiteLists = queryCompanyLikeName(gjjCompanyName);
                        if(Objects.nonNull(gjjCompanyWhiteLists)){
                            List<String> collect = gjjCompanyWhiteLists.stream().map(CompanyWhiteList::getCompanyName).collect(Collectors.toList());
                            for(String str:collect){
                                if(str.equals(gjjCompanyName)){
                                    logger.info("公积金企业名称在白名单表有数据，不做补录。授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
                                    gjjflag = false;
                                }
                            }
                        }
                    }else if(StringUtils.isBlank(gjjCompanyName)){
                        gjjflag = false;
                    }
                    if(dfflag && gjjflag){
                        insertCompanyWhite(code, dfCompanyName, gjjCompanyName, gjjRegisterAddr,nlsCreditInfoVO.getLmtApplySeq());
                    }else if(dfflag && !gjjflag){
                        insertCompanyWhite(code, dfCompanyName, null, gjjRegisterAddr,nlsCreditInfoVO.getLmtApplySeq());
                    }else if(!dfflag && gjjflag){
                        insertCompanyWhite(code, null, gjjCompanyName, gjjRegisterAddr,nlsCreditInfoVO.getLmtApplySeq());
                    }else{
                        logger.info("行内代发以及公积金在白名单表有数据，不做补录。授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
                    }

                }
            }catch (Exception e){
                logger.error("白名单补录出错，错误信息为"+e.getMessage()+"授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
                logger.info("流程继续完成绩效分配和调用风控通知。授信流水号为："+nlsCreditInfoVO.getLmtApplySeq());
            }
            //公积金报部分数据落表
            if(accNoResp != null){
                accNoResp.setIdentTp("10100");
                insertAcctInfo(accNoResp);
                insertAcctInfoDetail(accNoResp);
            }
            //推荐人工号
            String referrerId = nlsCreditInfoVO.getReferrerId();
            //管户机构
            String guanhuOrg = null;
            //出账机构
            String chuZhuangOrg = null;
            CusReferrerInfoVO voo  = new CusReferrerInfoVO();
            voo.setLmtApplySeq(nlsCreditInfoVO.getLmtApplySeq());
            CusReferrerInfoVO cusReferrerInfoVO = cusReferrerInfoService.queryChargeoffBrIdByPk(voo);
            if(cusReferrerInfoVO == null ){
                //若客户录入推荐人工号，且推荐人工号在营销业务经理库里存在，则获取推荐人归属机构，将该机构作为管户机构，出账机构与管户机构一致。
                if(StringUtils.isNotBlank(referrerId)){
                    KubUserVO kubUserVO = new KubUserVO();
                    kubUserVO.setUserid(referrerId);
                    KubUserVO vo = kubUserService.queryByPk(kubUserVO);
                    if(vo != null){
                        CusOrgEditVO cusVo = new CusOrgEditVO();
                        cusVo.setOrgNo(vo.getBrchno());
                        CusOrgEditVO cusOrgEditVO = cusOrgEditService.queryByOrgNo(cusVo);
                        if(Objects.nonNull(cusOrgEditVO)&& Objects.nonNull(cusOrgEditVO.getOrgNo()) ){
                            logger.info("命中规则一，查询业务维护表不为空，授信流水号为"+nlsCreditInfoVO.getLmtApplySeq());
                            guanhuOrg = vo.getBrchno();
                            chuZhuangOrg = vo.getBrchno();
                        }else{
                            logger.info("查询业务维护表为空，授信流水号为"+nlsCreditInfoVO.getLmtApplySeq());
                            Map<String, String> orgNo = getOrgNo(dfCompanyName, gjjCompanyName,nlsCreditInfoVO.getLmtApplySeq());
                            guanhuOrg = orgNo.get("guanhuOrg");
                            chuZhuangOrg = orgNo.get("chuZhuangOrg");
                            referrerId = orgNo.get("referrerId");
                        }
                    }else{
                        logger.info("查询柜员表为空，授信流水号为"+nlsCreditInfoVO.getLmtApplySeq());
                        Map<String, String> orgNo = getOrgNo(dfCompanyName, gjjCompanyName,nlsCreditInfoVO.getLmtApplySeq());
                        guanhuOrg = orgNo.get("guanhuOrg");
                        chuZhuangOrg = orgNo.get("chuZhuangOrg");
                        referrerId = orgNo.get("referrerId");
                    }
                }else {
                    logger.info("推荐人工号为空，授信流水号为"+nlsCreditInfoVO.getLmtApplySeq());
                    Map<String, String> orgNo = getOrgNo(dfCompanyName, gjjCompanyName,nlsCreditInfoVO.getLmtApplySeq());
                    guanhuOrg = orgNo.get("guanhuOrg");
                    chuZhuangOrg = orgNo.get("chuZhuangOrg");
                    referrerId = orgNo.get("referrerId");
                }
            }
            // 落推荐人信息表
            insertCusReferrerInfo(nlsCreditInfoVO,referrerId,guanhuOrg,chuZhuangOrg);
            //同步调用授信风控审批
            callFkSp(nlsCreditInfoVO);
            long endTime = System.currentTimeMillis();
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>白名单补录执行时长" + (endTime - startTime) + "毫秒<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        } catch (Exception e) {
            logger.error("企业白名单补录出错，错误信息为：{}", e.getMessage());
        }
    }

    /**
     * 抽出复用代码
     * @param dfCompanyName
     * @param gjjCompanyName
     * @return
     */
    private Map<String,String> getOrgNo(String dfCompanyName,String gjjCompanyName,String lmtApplySeq){
        Map<String,String> map = new HashMap<>();
        //否则，通过客户的单位名称匹配企业白名单里的“白名单上报机构号”，若值都不为空，则该机构作为管户机构，由绩效系统分配到该机构对应的虚拟柜员作为管户经理，
        //出账机构与管户机构一致
        boolean flag = false;
        CompanyWhiteListVO listVO = new CompanyWhiteListVO();
        if(StringUtils.isNotBlank(dfCompanyName)){
            listVO.setCompanyName(dfCompanyName);
            List<CompanyWhiteListVO> listVOList = this.companyWhiteListService.queryConditions(listVO);
            if(Objects.nonNull(listVOList)){
                String apperOrg = listVOList.stream().filter(s -> s.getAppearOrg() != null).map(CompanyWhiteListVO::getAppearOrg).collect(Collectors.joining());
                if(StringUtils.isNotBlank(apperOrg)){
                    CusOrgEditVO vo=new CusOrgEditVO();
                    vo.setOrgNo(apperOrg);
                    CusOrgEditVO cusOrgEditVO  = cusOrgEditService.queryByOrgNo(vo);
                    if(Objects.nonNull(cusOrgEditVO) && Objects.nonNull(cusOrgEditVO.getOrgNo())){
                        logger.info("命中规则二，查询业务维护表不为空，授信流水号为"+lmtApplySeq);
                        map.put("guanhuOrg",apperOrg);
                        map.put("chuZhuangOrg",apperOrg);
                        //全行都是XN+支行号
                        map.put("referrerId",XU_NI+apperOrg);
                        flag =true;
                    }
                }
            }
        }
        if(StringUtils.isNotBlank(gjjCompanyName) && !flag){
            listVO.setCompanyName(gjjCompanyName);
            List<CompanyWhiteListVO> listVOList = this.companyWhiteListService.queryConditions(listVO);
            if(Objects.nonNull(listVOList)){
                String apperOrg = listVOList.stream().filter(s -> s.getAppearOrg() != null).map(CompanyWhiteListVO::getAppearOrg).collect(Collectors.joining());
                if(StringUtils.isNotBlank(apperOrg)){
                    CusOrgEditVO vo=new CusOrgEditVO();
                    vo.setOrgNo(apperOrg);
                    CusOrgEditVO cusOrgEditVO  = cusOrgEditService.queryByOrgNo(vo);
                    if(Objects.nonNull(cusOrgEditVO) && Objects.nonNull(cusOrgEditVO.getOrgNo())){
                        logger.info("命中规则二，查询业务维护表不为空，授信流水号为"+lmtApplySeq);
                        map.put("guanhuOrg",apperOrg);
                        map.put("chuZhuangOrg",apperOrg);
                        //全行都是XN+支行号
                        map.put("referrerId",XU_NI+apperOrg);
                        flag = true;
                    }
                }
            }
        }
        if(!flag){
            logger.info("命中规则三，授信流水号为"+lmtApplySeq);
            map.put("guanhuOrg",ZHI_HUI_GUAN_HU_ORG);
            map.put("chuZhuangOrg",ZHI_HUI_CHU_ZHANG_ORG);
            //全行都是XN+支行号
            map.put("referrerId",ZHI_HUI_XU_NI_REF);
        }
        return map;
    }

    /**
     * 抽出方法
     * @param code
     * @param dfCompanyName
     * @param gjjCompanyName
     * @param gjjRegisterAddr
     * @throws Exception
     */
    private void insertCompanyWhite(String code, String dfCompanyName, String gjjCompanyName, String gjjRegisterAddr,String lmtAppySeq) throws Exception {
        String dfCompanyNameChange = getEnglishCompanyName(dfCompanyName);
        String gjjCompanyNameChange = getEnglishCompanyName(gjjCompanyName);
        Map<String,String> companyList = getRuleCompanyName(dfCompanyNameChange, gjjCompanyNameChange);
        if(companyList != null && companyList.size() == 1){
            if(StringUtils.isNotBlank(companyList.get("oneCompanyName"))){
                //以英文括号查询
                List<CompanyWhiteList> companyWhiteLists = queryCompanyWhiteList(companyList.get("oneCompanyName"));
                //以中文括号查询
                List<CompanyWhiteList> companyWhiteListss = queryCompanyWhiteList(getChineseCompanyName(dfCompanyName));
                //以行内代发名称查询
                List<CompanyWhiteList> companyWhiteListsss = queryCompanyWhiteList(dfCompanyName);
                if (companyWhiteLists != null && companyWhiteLists.size() >= 1 || companyWhiteListss!= null && companyWhiteListss.size() >=1
                        || (companyWhiteListsss!= null && companyWhiteListsss.size() >=1)) {
                    logger.info("企业白名单已有记录，不做补录。授信流水号为："+lmtAppySeq);
                }else {
                    insertCompanyWhiteInfoPrepare(dfCompanyName, null, gjjRegisterAddr,"N",code,lmtAppySeq);
                    insertCompanyWhiteInfoPrepare(null, gjjCompanyName, gjjRegisterAddr,"Y",code,lmtAppySeq);
                }
            }else if(StringUtils.isNotBlank(companyList.get("gjjCompanyName"))){
                List<CompanyWhiteList> companyWhiteLists = queryCompanyWhiteList(companyList.get("gjjCompanyName"));
                List<CompanyWhiteList> companyWhiteListss = queryCompanyWhiteList(getChineseCompanyName(gjjCompanyName));
                //以行内代发名称查询
                List<CompanyWhiteList> companyWhiteListsss = queryCompanyWhiteList(gjjCompanyName);
                if (companyWhiteLists != null && companyWhiteLists.size() >= 1 || companyWhiteListss != null && companyWhiteListss.size() >=1
                        || companyWhiteListsss != null && companyWhiteListsss.size() >=1) {
                    logger.info("企业白名单已有记录，不做补录。授信流水号为："+lmtAppySeq);
                }else {
                    insertCompanyWhiteInfoPrepare(null, gjjCompanyName, gjjRegisterAddr,"N",code,lmtAppySeq);
                }
            }else if(StringUtils.isNotBlank(companyList.get("dfCompanyName"))){
                List<CompanyWhiteList> companyWhiteLists = queryCompanyWhiteList(companyList.get("dfCompanyName"));
                List<CompanyWhiteList> companyWhiteListss = queryCompanyWhiteList(getChineseCompanyName(dfCompanyName));
                //以行内代发名称查询
                List<CompanyWhiteList> companyWhiteListsss = queryCompanyWhiteList(dfCompanyName);
                if (companyWhiteLists != null && companyWhiteLists.size() >= 1 && companyWhiteListss != null && companyWhiteListss.size() >= 1
                        && companyWhiteListsss != null && companyWhiteListsss.size() >= 1) {
                    logger.info("企业白名单已有记录，不做补录。授信流水号为："+lmtAppySeq);
                }else {
                    insertCompanyWhiteInfoPrepare(dfCompanyName, null, gjjRegisterAddr,"N",code,lmtAppySeq);
                }
            }
        }else  {
            List<CompanyWhiteList> dfCompanyWhiteLists = queryCompanyWhiteList(getEnglishCompanyName(dfCompanyName));
            List<CompanyWhiteList> gjjCompanyWhiteLists = queryCompanyWhiteList(getEnglishCompanyName(gjjCompanyName));
            List<CompanyWhiteList> dfCompanyWhiteListss = queryCompanyWhiteList(getChineseCompanyName(dfCompanyName));
            List<CompanyWhiteList> gjjCompanyWhiteListss = queryCompanyWhiteList(getChineseCompanyName(gjjCompanyName));
            //以行内代发名称查询
            List<CompanyWhiteList> dfCompanyWhiteListsss = queryCompanyWhiteList(dfCompanyName);
            List<CompanyWhiteList> gjjCompanyWhiteListsss = queryCompanyWhiteList(gjjCompanyName);
            if (dfCompanyWhiteLists != null && dfCompanyWhiteLists.size() >= 1 ||dfCompanyWhiteListss !=null && dfCompanyWhiteListss.size() >=1
                    || dfCompanyWhiteListsss !=null && dfCompanyWhiteListsss.size() >=1) {
                logger.info("行内代发企业信息存在，无需补录。授信流水号为："+lmtAppySeq);
            }else{
                insertCompanyWhiteInfoPrepare(dfCompanyName, null, gjjRegisterAddr,"N",code,lmtAppySeq);
            }
            if (gjjCompanyWhiteLists != null && gjjCompanyWhiteLists.size() >= 1 || gjjCompanyWhiteListss !=null && gjjCompanyWhiteListss.size() >=1
                    || gjjCompanyWhiteListsss !=null && gjjCompanyWhiteListsss.size() >=1) {
                logger.info("代发公积金企业信息存在，无需补录。授信流水号为："+lmtAppySeq);
            }else{
                insertCompanyWhiteInfoPrepare(null, gjjCompanyName, gjjRegisterAddr,"N",code,lmtAppySeq);
            }
        }
    }

    /**
     *
     * @param companyName
     * @return
     */
    private List<CompanyWhiteList> queryCompanyLikeName(String companyName){
        String likeCompanyName = getLikeCompanyName(companyName);
        CompanyWhiteListVO companyWhiteList = new CompanyWhiteListVO();
        companyWhiteList.setCompanyName(likeCompanyName);
        List<CompanyWhiteList> companyWhiteLists = companyWhiteListDao.queryCompanyLikeName(companyWhiteList);
        return companyWhiteLists;
    }


    /**
    *description：查询公积金企业信息
    *param：
    *return:
    *date: 2020/8/12 15:55
    *auther: gcb
    */
    private YedGjjAccNoInfoResponseBean getYedGjjAccNoInfoResponseBean(String certType, String certCode, String name) throws Exception {
        YedGjjCompnayInfoRequestBean gjjRequestBean = new YedGjjCompnayInfoRequestBean();
        gjjRequestBean.setIdentNo(certCode);
        if("10100".equalsIgnoreCase(certType)){
            gjjRequestBean.setIdentTp("01");
        }
        gjjRequestBean.setBeQryPrsnNm(name);
        YedGjjAccNoInfoResponseBean accNoResp = null;
        try{
            YedGjjCompanyInfoResponseBean responseBean = yedCompanyInfoService.queryGJJCompanyInfoForEDS(gjjRequestBean);
            if(Objects.nonNull(responseBean)){
                String gjjAccNo = responseBean.getPrvdntAcctNo();
                YedGjjAccInfoReqBean accInfoReqBean = new YedGjjAccInfoReqBean();
                accInfoReqBean.setPrvdntAcctNo(gjjAccNo);
                accNoResp = yedCompanyInfoService.queryGJJAccNOInfoForEDS(accInfoReqBean);
                return accNoResp;
            }
        }catch (Exception e){
            if(gjjCount.intValue() > 3){
                logger.info("重试3次查询公积金信息仍失败，请联系外数平台！！！");
                gjjCount.set(1);
                ReqAlarmJudgementBean reqAlarmJudgementBean = new ReqAlarmJudgementBean();
                reqAlarmJudgementBean.setAlrmInf("重试3次查询鹏元企业信息仍失败，请联系互开系统！！！");
                try {
                    getrespAlarmJudgementBean(reqAlarmJudgementBean);
                } catch (Exception alarme) {
                    alarme.printStackTrace();
                    logger.debug("调用告警接口异常！" + alarme.getMessage());
                }
                throw new Exception(e.getMessage());
            }
            while(gjjCount.intValue() <= 3){
                Thread.sleep(5000);
                logger.error("查询公积金出错，出错信息为："+e.getMessage());
                logger.info("开始重试第"+gjjCount.intValue()+"次查询公积金信息！！！");
                gjjCount.incrementAndGet();
                getYedGjjAccNoInfoResponseBean(certType,certCode,name);
            }
        }
       return accNoResp;
    }

    /**
    *description：查询公积金账户信息表
    *param：
    *return:
    *date: 2020/8/12 15:52
    *auther: gcb
    */
    private List<AcctInfoVO> getAcctInfoVOS(String certType, String certCode) throws Exception {
        AcctInfoVO acctInfo = new AcctInfoVO();
        acctInfo.setCertType(certType);
        acctInfo.setCertCode(certCode);
        acctInfo.setPrdId("11110004");
        return acctInfoService.queryCertCodeAndCertTypeAndPrdId(acctInfo);
    }


    /**
     * description：插入公积金账户详细信息表
     * param：
     * return:
     * date: 2020/8/12 14:57
     * auther: gcb
     */
    private void insertAcctInfoDetail(YedGjjAccNoInfoResponseBean accNoResp) throws Exception {
        List<Map> infoDetailList = accNoResp.getPrvdntAcctInfArry();
        for (Map infoDetail : infoDetailList) {
            String object = JSONObject.toJSONString(infoDetail);
            YedGjjAcctInfoDetailRespBean yedGjjAcctInfoLoanRespBean = JSONObject.parseObject(object, YedGjjAcctInfoDetailRespBean.class);
            AcctInfoDetailVO infoDetailVO = new AcctInfoDetailVO();
            infoDetailVO.setPrvdntAcctNo1(yedGjjAcctInfoLoanRespBean.getPrvdntAcctNo1());
            infoDetailVO.setOpnAcctDt(yedGjjAcctInfoLoanRespBean.getOpnAcctDt());
            infoDetailVO.setPayStopDt(yedGjjAcctInfoLoanRespBean.getPayStopDt());
            infoDetailVO.setCrnMnthPayUnitNm(accNoResp.getCorpNm());
            infoDetailVO.setCrnBal(new BigDecimal(yedGjjAcctInfoLoanRespBean.getCrnBal()));
            infoDetailVO.setCertCode(accNoResp.getIdentNo());
            infoDetailVO.setCertType(accNoResp.getIdentTp());
            infoDetailVO.setPrdId("11110004");
            infoDetailVO.setRemark("白名单导入插入");
            infoDetailVO.setCreateTime(DateUtility.getCurrDateTime());
            acctInfoDetailService.insert(infoDetailVO);
        }
    }

    /**
     * description：插入公积金账户信息表
     * param：
     * return:
     * date: 2020/8/12 14:44
     * auther: gcb
     */
    private void insertAcctInfo(YedGjjAccNoInfoResponseBean accNoResp) throws Exception {
        AcctInfoVO acctInfo = new AcctInfoVO();
        acctInfo.setInfQrySrc(accNoResp.getInfQrySrc());
        acctInfo.setCustNm(accNoResp.getCustNm());
        acctInfo.setPrvdntAcctNo(accNoResp.getPrvdntAcctNo());
        acctInfo.setCertType(accNoResp.getIdentTp());
        acctInfo.setCertCode(accNoResp.getIdentNo());
        acctInfo.setPreTaxSlryTotAmt(new BigDecimal(accNoResp.getPreTaxSlryTotAmt()));
        acctInfo.setMblNo(accNoResp.getMblNo());
        acctInfo.setCorpNm(accNoResp.getCorpNm());
        acctInfo.setUnitRgstNo(accNoResp.getUnitRgstNo());
        acctInfo.setFrstTmsRgstyTm(accNoResp.getFrstTmsRgstyTm());
        acctInfo.setOibc(accNoResp.getOIBC());
        acctInfo.setBsnLicNo(accNoResp.getBsnLicNo());
        acctInfo.setChrctrstcCd(accNoResp.getChrctrstcCd());
        acctInfo.setCorpAddr(accNoResp.getCorpAddr());
        acctInfo.setUnitPaySt(accNoResp.getUnitPaySt());
        acctInfo.setUnitPayCapitlSrc(accNoResp.getUnitPayCapitlSrc());
        acctInfo.setLglRprs(accNoResp.getLglRprs());
        acctInfo.setUnitCtcMd(accNoResp.getUnitCtcMd());
        acctInfo.setPrdId("11110004");
        acctInfo.setRemark("白名单补录时插入数据");
        acctInfo.setCreateTime(DateUtility.getCurrDateTime());
        acctInfoService.insert(acctInfo);
    }

    /**
     * description：补录白名单信息准备信息
     * param：
     * return:
     * date: 2020/8/12 10:17
     * auther: gcb
     */
    private void insertCompanyWhiteInfoPrepare(String dfCompanyName, String gjjCompanyName,String registerAddr,String pengYuan,String code,String lmtAppySeq) throws Exception {
        YedCompanyInfoReqBean yedCompanyInfoReqBean = null;
        String companyName = null;
        try{
            if("Y".equals(pengYuan)){
                String value  = redisLockCluster.getJedisCluster().get(PENG_YUAN_PRE + code);
                if(StringUtils.isNotBlank(value)) {
                    yedCompanyInfoReqBean = JSONObject.parseObject(value,YedCompanyInfoReqBean.class);
                }
                companyName = gjjCompanyName;
            }else if (StringUtils.isBlank(dfCompanyName) && StringUtils.isNotBlank(gjjCompanyName)) {
                yedCompanyInfoReqBean = queryPengYuanCompanyInfo(gjjCompanyName);
                companyName = gjjCompanyName;
            } else {
                yedCompanyInfoReqBean = queryPengYuanCompanyInfo(dfCompanyName);
                companyName = dfCompanyName;
                if((StringUtils.isNotBlank(dfCompanyName) && StringUtils.isBlank(gjjCompanyName) && yedCompanyInfoReqBean != null)){
                    String nValue = JSONObject.toJSONString(yedCompanyInfoReqBean);
                    redisLockCluster.getJedisCluster().set(PENG_YUAN_PRE + code,nValue);
                    redisLockCluster.getJedisCluster().expire(PENG_YUAN_PRE + code,600);
                }
            }
        }catch (Exception e){
            if(pengYuanCount.intValue() > 3){
                logger.info("重试3次查询鹏元企业信息仍失败，请联系互开系统！！！");
                pengYuanCount.set(1);
                ReqAlarmJudgementBean reqAlarmJudgementBean = new ReqAlarmJudgementBean();
                reqAlarmJudgementBean.setAlrmInf("重试3次查询鹏元企业信息仍失败，请联系互开系统！！！");
                try {
                    getrespAlarmJudgementBean(reqAlarmJudgementBean);
                } catch (Exception alarme) {
                    alarme.printStackTrace();
                    logger.debug("调用告警接口异常！" + alarme.getMessage());
                }
                throw new Exception(e.getMessage());
            }
            while(pengYuanCount.intValue() <= 3){
                Thread.sleep(5000);
                logger.error("查询鹏元企业信息出错，出错信息为："+e.getMessage());
                logger.info("开始重试第"+pengYuanCount.incrementAndGet()+"次查询鹏元企业信息！！！");
                pengYuanCount.incrementAndGet();
                insertCompanyWhiteInfoPrepare(dfCompanyName,gjjCompanyName,registerAddr,pengYuan,code,lmtAppySeq);
            }
        }
        if (yedCompanyInfoReqBean == null) {
            logger.error("查询鹏元没有返回,不做补录。授信流水号为"+lmtAppySeq);
        }else{
            List<Map> qryRsltArry = yedCompanyInfoReqBean.getQryRsltArry();
            for (Map resultReqBean : qryRsltArry) {
                Object entpBscInfStrct = resultReqBean.get("EntpBscInfStrct");
                String entpBscInfStrctString = JSONObject.toJSONString(entpBscInfStrct);
                YedPengYuanCompanyInfoRespBean yedPengYuanCompanyInfoRespBean = JSONObject.parseObject(entpBscInfStrctString, YedPengYuanCompanyInfoRespBean.class);
                String entpNm = null;
                String entpSt = null;
                String entpTp = null;
                if(Objects.nonNull(yedPengYuanCompanyInfoRespBean)){
                    entpNm = yedPengYuanCompanyInfoRespBean.getEntpNm();
                    entpSt = yedPengYuanCompanyInfoRespBean.getEntpSt();
                    entpTp = yedPengYuanCompanyInfoRespBean.getEntpTp();
                }
                yedPengYuanCompanyInfoRespBean.setRegisterAddr(registerAddr);
                //代发或者公积金企业名称，以及鹏元返回的企业名称做去空格处理
                if ( StringUtils.isNotBlank(entpSt) && CompanyStatusEnum.ZAI_YING.getKey().equals(entpSt)) {
                    List<CompanyWhiteList> companys = queryCompanyWhiteList(getNewCompanyName(companyName));
                    String companyClass = null;
                    String companyType = null;
                    //按照匹配到的白名单开始补录
                    if (companys != null && companys.size() >= 1) {
                        companyClass = companys.get(0).getCompanyClass();
                        companyType = companys.get(0).getCompanyType();
                    } else {
                        //按照规则开始补录
                        if(StringUtils.isBlank(entpTp)){
                            logger.info("鹏元返回企业类型不符合补录规则，流水号为"+lmtAppySeq);
                            companyClass = "D";
                            companyType = "9";
                        }else{
                            companyType = CompanyTypeEnum.parseKey(entpTp);
                        }
                        if (companyType.contains("国有")) {
                            companyClass = "B";
                            companyType = "3";
                        } else if (companyType.contains("事业")) {
                            companyClass = "A";
                            companyType = "2";
                        } else {
                            companyClass = "C";
                            companyType = "8";
                        }
                    }
                    if (StringUtils.isNotBlank(dfCompanyName) && !companyClass.equals("D")) {
                        insertCompanyWhiteInfo(companyName, yedPengYuanCompanyInfoRespBean, companyClass, companyType,registerAddr);
                    }else if (StringUtils.isNotBlank(gjjCompanyName) && StringUtils.isNotBlank(companyClass) && !companyClass.equals("C") && !companyClass.equals("D")) {
                        insertCompanyWhiteInfo(companyName, yedPengYuanCompanyInfoRespBean, companyClass, companyType,registerAddr);
                    }else{
                        logger.info("行内代发企业为空，同时公积金返回的企业类型不是国有或者事业类型，不做补录！授信流水号为"+lmtAppySeq);
                        logger.info("补录公司名称为："+companyName+"鹏元返回企业状态为："+CompanyStatusEnum.parseKey(entpSt)+",鹏元返回企业名称为："
                                +entpNm+",鹏元返回企业状态不符或者补录公司名称与鹏元返回名称不符，不做补录！！！授信流水号"+lmtAppySeq);
                    }
                }
            }
        }

    }

    /**
     * description：补录百名单
     * param：
     * return:
     * date: 2020/8/12 10:22
     * auther: gcb
     */
    private void insertCompanyWhiteInfo(String companyName, YedPengYuanCompanyInfoRespBean resultReqBean, String companyClass, String companyType,String registerAddr) {
        CompanyWhiteList vo = new CompanyWhiteList();
        vo.setCompanyId(UUIDUtil.getUUID());
        vo.setCompanyAddr(registerAddr);
        vo.setCompanyName(companyName);
        vo.setCompanyType(companyType);
        vo.setRegisterTime(DateUtility.format8To10(resultReqBean.getRgstrnTm()));
        vo.setStatus(resultReqBean.getEntpSt());
        vo.setCompanyClass(companyClass);
        vo.setEffectiveStartTime(resultReqBean.getStrtDt());
        vo.setEffectiveEndTime(resultReqBean.getEndDt());
        vo.setUpdateTime(DateUtility.getCurrTime());
        vo.setUpdateDate(DateUtility.getCurrDate());
        vo.setRemark("白名单补录时插入");
        vo.setImportDate(DateUtility.getCurrDate());
        vo.setImportEmpNo("system");
        vo.setImportEmpName("system");
        vo.setUpdateNo("system");
        vo.setUpdateName("system");
        companyWhiteListDao.insert(vo);
    }

    /**
     * description：查询鹏元企业信息
     * param：
     * return:
     * date: 2020/8/12 9:56
     * auther: gcb
     */
    private YedCompanyInfoReqBean queryPengYuanCompanyInfo(String dfCompanyName) throws Exception {
        YedCompanyInfoRequestBean requestBean = new YedCompanyInfoRequestBean();
        requestBean.setEntpNm(dfCompanyName);
        return yedCompanyInfoService.queryCompanyInfoForIOP(requestBean);
    }

    /**
     * description：查询企业白名单信息
     * param：
     * return:
     * date: 2020/8/12 9:42
     * auther: gcb
     */
    private List<CompanyWhiteList> queryCompanyWhiteList(String companyName) {
        if(StringUtils.isNotBlank(companyName)){
            CompanyWhiteList companyWhiteList = new CompanyWhiteList();
            companyWhiteList.setCompanyName(companyName);
            List<CompanyWhiteList> companyWhiteLists = companyWhiteListDao.queryCompanyName(companyWhiteList);
            return companyWhiteLists;
        }
       return null;
    }

    private void callFkSp(NlsCreditInfoVO nlsCreditInfoVO){
        // 授信申请流水号
        String applySeq = nlsCreditInfoVO.getLmtApplySeq();
        logger.info("优e贷授信风控审批接口调用开始执行,流水号:" + applySeq);
        try {
            TraceUtil.setTraceId(nlsCreditInfoVO.getGlobalSerno());
            String certType = nlsCreditInfoVO.getCertType();
            String certCode = nlsCreditInfoVO.getCertCode();

            /*当前贷款逾期状态(网贷) 其中'0'代表无逾期,'1'代表有逾期*/
            AccLoanVO accLoanVO = accLoanService.queryOverdue(certType, certCode);
            String CurrentLoanState=Objects.isNull(accLoanVO) ? ConsoleConstant.NOT_OVERDUE :ConsoleConstant.OVERDUE;

            /*占用额度*/
            //查询网贷占用额度
           BigDecimal preOccAmt = limitControlsService.getPreOccAmt(certCode, certType);

            /**是否存在授信在途申请 0-否,1-是**/
            String creditDuring = limitControlsService.isCreditDuring(certType, certCode,applySeq)? YedEnums.IsDuringEnum.YES.getValue():YedEnums.IsDuringEnum.NO.getValue();

            /**是否存在用信在途申请**/
            NlsApplyInfoVO nlsApplyInfoVO =new NlsApplyInfoVO();
            nlsApplyInfoVO.setCertType(certType);
            nlsApplyInfoVO.setCertCode(certCode);
            nlsApplyInfoVO.setApplyAmt(BigDecimal.ZERO);
           String isDuring = limitControlsService.isDuring(nlsApplyInfoVO)?YedEnums.IsDuringEnum.YES.getValue():YedEnums.IsDuringEnum.NO.getValue();

            YedCreditRiskApproveReq credit = YedCreditRiskApproveReq.builder().build();
            QryRptsInfArryBean qryRptsInfArryBean= QryRptsInfArryBean.builder()
                    //部门号
                    .DeptNo(InstitutionEnums.InstitutionEnum.GZYHZHYHZX.getCode())
                    //.UsrNo("")用户编号 风控从报文头拿
                    //申请编号
                    .AppNo(nlsCreditInfoVO.getLmtApplySeq())
                    //主卡申请人姓名
                    .MainCardAplcNm(nlsCreditInfoVO.getCusName())
                    //申请人证件号码
                    .AplcIdentNo(certCode)
                    //申请人证件类型
                    .AplcIdentTp(certType)
                    //证件有效期
                    .IdentVldty(nlsCreditInfoVO.getCertEndDt())
                    //年龄
                    .Age(BigDecimal.valueOf(ValidationUtils.getAgeFromIdNumber(certCode)))
                    //性别
                    .Gnd(nlsCreditInfoVO.getGender())
                    //国籍
                    .Nation(nlsCreditInfoVO.getNational())
                    //联系电话号
                    .CtcTelNo(nlsCreditInfoVO.getIndivMobile())
                    //婚姻状态
                    .MrtlSt(nlsCreditInfoVO.getMrgSitu())
                    //职业
                    .Crr(nlsCreditInfoVO.getProfession())
                    //家庭地址
                    .FamAddr(nlsCreditInfoVO.getIndivRsdAddr())
                    //单位地址
                    .CorpAddr(nlsCreditInfoVO.getWrkCorpAddr())
                    //联系人电话
                    .CrspTel(nlsCreditInfoVO.getEmergencyContactPhone())
                    //联系人姓名
                    .CrspNm(nlsCreditInfoVO.getEmergencyContactName())
                    //与联系人的关系类型
                    .WthCrspRelaTp(nlsCreditInfoVO.getEmergencyContactRelate())
                    //存量业务标志,因为网贷在授信进件申请的时候已经做了判断，重复授信的已经拒绝了，所以这里都是否
                    .StkBsnFlg(YedEnums.IsStockEnum.NO.getValue())
                    //客户申请所在城市
                    .CustAppWrbtCity(nlsCreditInfoVO.getCity())
                    //当前贷款状态
                    .CrnLoanSt(CurrentLoanState)
                    //占用额度
                   .NetwrkLoanOcptnLmt(preOccAmt)
                    //是否存在授信在途申请
                   .InTrnstCrAppFlg(creditDuring)
                    //是否存在用信在途申请
                   .InTrnstUseCrdtAppFlg(isDuring)
                    .build();
            credit.setQryRptsInfArry(Collections.singletonList(qryRptsInfArryBean));

                try {
                    YedCreditRiskApproveResp service = creditRiskApproveService.service(credit);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("授信申请-风控审批异常：" + e.getMessage());
                    //修改授信审批状态
                    nlsCreditInfoVO.setApprvSts(MsLoanConstant.NlsApplyStateEnum.REJECT.VALUE);
                    nlsCreditInfoVO.setRejectReason(e.getMessage());
                    nlsCreditInfoVO.setRefuseCause(e.getMessage());
                    nlsCreditInfoService.updateByPk(nlsCreditInfoVO);
                }
        } catch (Exception e) {

            e.printStackTrace();
        }finally {
            TraceUtil.clear();
            logger.info("优e贷授信风控审批接口调用结束，流水号："+nlsCreditInfoVO.getLmtApplySeq());
        }
    }

    /**
     * 插入客户推荐人信息表
     * @param nlsCreditInfoVO
     * @throws Exception
     */
    private void insertCusReferrerInfo(NlsCreditInfoVO nlsCreditInfoVO,String referrerId,String guanHuOrg,String chuZhuangOrg) throws Exception {
        CusReferrerInfoVO vo  = new CusReferrerInfoVO();
        vo.setLmtApplySeq(nlsCreditInfoVO.getLmtApplySeq());
        CusReferrerInfoVO cusReferrerInfoVO = cusReferrerInfoService.queryChargeoffBrIdByPk(vo);
        if(!Objects.nonNull(cusReferrerInfoVO)){
            CusReferrerInfoVO cus=CusReferrerInfoVO.builder()
                    //授信申请流水号
                    .lmtApplySeq(nlsCreditInfoVO.getLmtApplySeq())
                    //客户名称
                    .cusName(nlsCreditInfoVO.getCusName())
                    //证件类型
                    .certType(nlsCreditInfoVO.getCertType())
                    //证件号码
                    .certCode(nlsCreditInfoVO.getCertCode())
                    //产品id
                    .prdId(nlsCreditInfoVO.getPrdId())
                    //管户机构
                    .mainBrId(guanHuOrg)
                    //出账机构
                    .chargeOffBrId(chuZhuangOrg)
                    //推荐人工号
                    .referrerId(referrerId)
                    //最后修改时间
                    .lastModifyTime(TimeUtil.getCurrentDateTime())
                    //创建日期
                    .createTime(TimeUtil.getCurrentDateTime())
                    .build();
            int result = cusReferrerInfoService.insertCusReferrerInfo(cus);
            if (result == -1) {
                throw new Exception("=======>【优e贷授信】插入客户推荐人信息表失败<=======");
            }
        }
    }

    /**
     *
     * 调用颖风写的告警判断服务
     *
     * @param reqAlarmJudgementBean
     * @return
     * @throws Exception
     * @author liyakui
     * @since 2019年1月28日 上午8:36:25
     * @version 1.0
     */
    public RespAlarmJudgementBean getrespAlarmJudgementBean(ReqAlarmJudgementBean reqAlarmJudgementBean) throws Exception {
        RespAlarmJudgementBean respAlarmJudgementBean = null;
        try {
            // 调用颖风写的告警判断服务
            reqAlarmJudgementBean.setMonObjNm("优e贷");
            reqAlarmJudgementBean.setMonObjSpfTpVal("外部接口");
            reqAlarmJudgementBean.setMonObjLctr(InetAddress.getLocalHost().getHostAddress());// 获取本机IP
            reqAlarmJudgementBean.setAlrmTmstmp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((new Date())));
            reqAlarmJudgementBean.setMonAlrmLvl("3");
            respAlarmJudgementBean = alarmJudgementService.alarmJudgement(reqAlarmJudgementBean);
            logger.debug("调用告警判断返回码：【" + respAlarmJudgementBean.getRetCd() + "】，返回信息：【" + respAlarmJudgementBean.getRetMsg() + "】");
        } catch (Exception e) {
            logger.info("调用告警接口异常！" + e.getMessage());
            throw e;
        }
        return respAlarmJudgementBean;
    }

}
